package com.adee.gulimall.ware.service.impl;

import com.adee.gulimall.common.constant.WareConstant;
import com.adee.gulimall.common.utils.PageUtils;
import com.adee.gulimall.common.utils.Query;
import com.adee.gulimall.ware.dao.PurchaseDao;
import com.adee.gulimall.ware.dao.PurchaseDetailDao;
import com.adee.gulimall.ware.entity.PurchaseDetailEntity;
import com.adee.gulimall.ware.entity.PurchaseEntity;
import com.adee.gulimall.ware.service.PurchaseDetailService;
import com.adee.gulimall.ware.service.PurchaseService;
import com.adee.gulimall.ware.service.WareSkuService;
import com.adee.gulimall.ware.vo.MergeVo;
import com.adee.gulimall.ware.vo.PurchaseDoneVo;
import com.adee.gulimall.ware.vo.PurchaseItemDoneVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    PurchaseDetailService purchaseDetailService;

    @Autowired
    PurchaseDetailDao purchaseDetailDao;

    @Autowired
    WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceive(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 0).or().eq("status", 1);
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    // 采购需求合并到一个采购单
    @Transactional
    @Override
    public void merge(MergeVo vo) {
        Long purchaseId = vo.getPurchaseId();
        if(purchaseId != null) {
            // 确认采购单状态是【新建】或【已分配】
            PurchaseEntity p = this.getById(purchaseId);
            Integer status = p.getStatus();
            if(status != WareConstant.PurchaseStatusEnum.CREATED.getCode() &&
                    status != WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                throw new RuntimeException("采购单状态错误:" + status);
            }
        } else {
            // 1.新建一个
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        List<Long> items = vo.getItems(); // 采购需求列表
        boolean detailsStatusNormal = true;
        List<PurchaseDetailEntity> detailList = purchaseDetailDao.selectBatchIds(items);
        // 确认采购需求的状态是【新建】或【已分配】
        List<Long> errorIds = new ArrayList<>();
        for (PurchaseDetailEntity d : detailList) {
            Integer status = d.getStatus();
            if(status != WareConstant.PurchaseDetailStatusEnum.CREATED.getCode() &&
                    status != WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode()) {
                errorIds.add(d.getId());
            }
        }
        if(errorIds.size() > 0) {
            throw new RuntimeException("采购需求状态错误:" + errorIds.toString());
        }
        // 采购需求状态都没问题，则批量更新状态为【正在采购】
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> updateList = items.stream().map(id -> {
            PurchaseDetailEntity d = new PurchaseDetailEntity();
            d.setId(id);
            d.setPurchaseId(finalPurchaseId);
            d.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode()); // 已分配
            return d;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(updateList);
    }

    /**
     * 采购人员领取采购单
     */
    @Override
    public void received(Long[] ids) {
        if(ids == null || ids.length == 0) return;
        // 1.确认当前采购单是【新建】或【已分配】状态
        List<PurchaseEntity> list =
                this.baseMapper.selectBatchIds(Arrays.stream(ids).collect(Collectors.toList()));
        List<PurchaseEntity> canList = list.stream().filter(p ->
                        p.getStatus() == WareConstant.PurchaseStatusEnum.CREATED.getCode() ||
                                p.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode())
                .collect(Collectors.toList());

        canList.forEach(p -> {
            PurchaseEntity np = new PurchaseEntity();
            np.setId(p.getId());
            np.setStatus(WareConstant.PurchaseStatusEnum.RECEIVED.getCode());
            np.setUpdateTime(new Date());
            // 2.改变采购单状态
            this.getBaseMapper().updateById(np);
            // 3.改变采购项状态
            PurchaseDetailEntity detail = new PurchaseDetailEntity();
            detail.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
            purchaseDetailService.update(detail,
                    new UpdateWrapper<PurchaseDetailEntity>()
                            .eq("purchase_id", p.getId()));
        });
    }

    // 采购完成
    @Transactional
    @Override
    public void done(PurchaseDoneVo vo) {
        List<PurchaseItemDoneVo> items = vo.getItems();
        Integer purchaseStatus = WareConstant.PurchaseStatusEnum.FINISHED.getCode();
        for (PurchaseItemDoneVo item : items) {
            if(item.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()) {
                purchaseStatus = WareConstant.PurchaseStatusEnum.HASERROR.getCode();
                break;
            }
        }
        // 1.更新采购单状态
        Long purchaseId = vo.getId();
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setStatus(purchaseStatus);
        purchaseEntity.setId(purchaseId);
        this.updateById(purchaseEntity);
        // 2.更新采购项状态
        for (PurchaseItemDoneVo item : items) {
            PurchaseDetailEntity d = new PurchaseDetailEntity();
            d.setId(item.getItemId());
            d.setStatus(item.getStatus());
            // 数据库表中无reason字段，后期可完善
            purchaseDetailService.updateById(d);
            // 3.将成功采购的采购项入库
            if(item.getStatus() == WareConstant.PurchaseDetailStatusEnum.FINISHED.getCode()) {
                PurchaseDetailEntity detail = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(detail.getSkuId(), detail.getWareId(), detail.getSkuNum());
            }
        }
    }

}